import numpy as np










class Activation:
    def __init__(self) -> None:
        pass
    def __call__(self,z:np.matrix) -> np.matrix:
        return z
    def Da_dz(self,A:np.matrix) -> np.matrix:
        return A
    
    def Id(self)-> int:
        """
        返回激活函数ID
        """
        return 0
    
    
    
    
class Sigmoid(Activation):
    def __init__(self) -> None:
        super().__init__()
        
    
    def __call__(self, z:np.matrix) -> np.matrix:
        return 1/(1+np.exp(-z))
    
    def Da_dz(self, A: np.matrix) -> np.matrix:
        return A * (1 - A) 
    
    def Id(self) -> int:
        return 1
    
    
    
class Relu(Activation):
    def __init__(self) -> None:
        super().__init__()
        
    def __call__(self, z:np.matrix) -> np.matrix:
        return np.maximum(z,0)
    
    def Da_dz(self, A:np.matrix) -> np.matrix:
        return np.int64(A>0)

    def Id(self) -> int:
        return 2
    
class Softmax(Activation):
    def __init__(self) -> None:
        super().__init__()
        
    def __call__(self, z: np.matrix) -> np.matrix:
        ez = np.exp(z)
        
        tmp = np.sum(ez,axis=0).reshape(1,-1)
        res = ez/tmp
        return res
    
    def Id(self) -> int:
        return 3


class  Liner(Activation):
    def __init__(self) -> None:
        super().__init__()
        
    def __call__(self, z: np.matrix) -> np.matrix:
        return z

    def Da_dz(self, A: np.matrix) -> np.matrix:
        return 1
    
    def Id(self) -> int:
        return 4 

ActTypeMap = {
    1: Sigmoid,
    2: Relu,
    3: Softmax,
    4: Liner
}


if __name__ == '__main__':
    a = np.array([[1,5,-5,7],[1,5,-5,7]])

    print(a.shape)
    print(a/np.sum(a,axis=0))
    print(np.sum((a/np.sum(a,axis=0)),axis=0))
    pass